package com.purchase.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.converters.DateConverter;

import com.purchase.entity.AppUser;

/**
 * @author liuhoujie
 * @DESC map转pojo工具类
 * @param bean
 * @param properties
 */
public final class MyBeanUtils {
	private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	private MyBeanUtils() {
	}

	/**
	 * @author liuhoujie
	 * @DESC beanutils工具(加时间格式处理)
	 * @param bean
	 * @param properties
	 */
	public static <T> T populate(T pojo, Map<String, Object> properties) {
		if (pojo instanceof Integer) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof String) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof Double) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof Float) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof Long) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof Boolean) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof Date) {
			System.err.println("pojo type error !");
			return null;
		}
		try {
			// 处理时间格式
			DateConverter dateConverter = new DateConverter(null);
			// 设置日期格式
			dateConverter.setPatterns(new String[] { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm" });
			// 注册格式
			ConvertUtils.register(dateConverter, Date.class);
			// 注册String->decimal
			// StringConverter stringConverter = new StringConverter(null);
			// ConvertUtils.register(stringConverter, BigDecimal.class);
			// 封装数据
			BeanUtils.populate(pojo, properties);
		} catch (IllegalAccessException | InvocationTargetException e) {
			throw new RuntimeException(e);
		}
		return pojo;
	}

	/**
	 * @author liuhoujie
	 * @DESC 自定义map转pojo工具(加时间格式处理)
	 * @param bean
	 * @param properties
	 * @remark 时间戳格式转date,命名时需要带time或者date
	 */
	@SuppressWarnings("unused")
	public static <T> T populateIgnoreCase(T pojo, Map<String, Object> map) {
		if (pojo instanceof Integer) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof String) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof Double) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof Float) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof Long) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof Boolean) {
			System.err.println("pojo type error !");
			return null;
		} else if (pojo instanceof Date) {
			System.err.println("pojo type error !");
			return null;
		}
		/* 获取pojo的类型clazz */
		Class<? extends Object> clazz = pojo.getClass();
		/* 获取pojo的内部方法 */
		Field[] fields = clazz.getDeclaredFields();
		/* 私有方法授权 */
		Field.setAccessible(fields, true);
		try {
			/* 循环遍历map */
			for (Map.Entry<String, Object> entry : map.entrySet()) {
				/* map循环当前获取到当前的key */
				String key = entry.getKey();
				/* map循环当前获取到当前的value */
				Object value = entry.getValue();
				/* 循环遍历pojo字段的名和值 */
				for (Field field : fields) {
					String name = field.getName();
					if (name.equalsIgnoreCase(key)) {
						/* 判断时间的格式是否为时间戳 */
						if (name.toUpperCase().contains("TIME") && (value + "").matches("\\d+")) {
							field.set(pojo, format.parse(format.format(value)));
						} else {
							field.set(pojo, value);
						}
						/* 如果找到对应字段结束循环,提高效率 */
						break;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return pojo;
	}

	/**
	 * @desc 对象转化map 去除空键值对
	 * @param pojo
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static <T> Map describeAndNotBlank(T pojo) {
		Map resultMap = new HashMap<>();
		try {
			resultMap = PropertyUtils.describe(pojo);
		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
			e.printStackTrace();
		} finally {
			resultMap.remove("class");
			Iterator iterator = resultMap.keySet().iterator();
			while (iterator.hasNext()) {
				Object key = (Object) iterator.next();
				Object value = resultMap.get(key);
				if (value == null||key==null) {
					iterator.remove();
				}
			}
		}
		return resultMap;
	}
	
	/**
	 * @desc 对象转化map
	 * @param pojo
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static <T> Map describe(T pojo) {
		Map resultMap = new HashMap<>();
		try {
			resultMap = PropertyUtils.describe(pojo);
		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
			e.printStackTrace();
		} finally {
			resultMap.remove("class");
		}
		return resultMap;
	}
	
	
//	public static void main(String[] args) {
//		AppUser appuser = new AppUser();
//		appuser.setWxUid("sdfafasd");
//		appuser.setNickName("nickName");
//		appuser.setOpenId("dfadfadsf");
//		Map describe222 = describe(appuser);
//		System.out.println(describe222);
//	}
}
